<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        *{
            margin: 0;
            padding: 0;
        }
        img {
            vertical-align: top;
        }

        /*小盒子*/
        #div-small {
            width: 350px;
            height: 380px;
            outline: 2px solid black;
            position: absolute;
            top: 50px;
            left: 0;
            /*鼠标变成小手样式*/
            cursor: pointer;
        }

        /*大盒子*/
        #div-big {
            width: 500px;
            height: 500px;
            outline: 2px solid black;
            position: absolute;
            left: 380px;
            top: 50px;
            overflow: hidden;
            display: none;
        }

        /*遮罩层*/
        #div-mask {
            width: 150px;
            height: 150px;
            background-color: aqua;
            opacity: 0.5;
            position: absolute;
            top: 0;
            left: 0;
            /*对鼠标事件失去作用*/
            pointer-events: none;
            display: none;
        }
    </style>
</head>

<body>
    <div id="div-small">
        <img src="./img/apple.png" id="img-small">
        <div id="div-mask"></div>
    </div>
    <div id="div-big">
        <img src="./img/apple.png" id="img-big">
    </div>
</body>
<script>
    //获取标签
    let div_small = document.querySelector("#div-small");
    let div_big = document.querySelector("#div-big");
    let div_mask = document.querySelector("#div-mask");
    let img_small = document.querySelector("#img-small");
    let img_big = document.querySelector("#img-big");



    //假定鼠标控制遮罩层在当前盒子的正中间，我们需要先求出遮罩层左上角的坐标（x=e.offsetX-mask.offsetWidth,y=e.offsetY-mask.offsetHeight）

    //鼠标移入事件
    div_small.onmouseover = function () {
        //鼠标移入小盒子时,遮罩层和大盒子显示
        div_mask.style["display"] = "block";
        div_big.style["display"] = "block";
    }

    //鼠标移出事件
    div_small.onmouseout = function () {
        //鼠标移出小盒子时,遮罩层和大盒子消失
        div_mask.style["display"] = "none";
        div_big.style["display"] = "none";
        //同时让大盒子图片回到原位
        img_big.style["margin-left"] = 0;
        img_big.style["margin-top"] = 0;
    }

    //(小盒子内)鼠标移动事件
    div_small.onmousemove = function (e) {

        //通过1和2可以确保鼠标在遮罩层的正中间
        //1.获取鼠标在小盒子的位置x0,y0
        let x0 = e.offsetX;
        let y0 = e.offsetY;

        //2.计算当前位置(左上角)
        let cur_x = x0 - div_mask.offsetWidth / 2;
        let cur_y = y0 - div_mask.offsetHeight / 2;

        //2-1.防止遮罩越界(超出盒子区域),超出则拉回
        cur_x = cur_x < 0 ? 0 : cur_x;
        cur_x = cur_x > div_small.offsetWidth - div_mask.offsetWidth ? div_small.offsetWidth - div_mask.offsetWidth : cur_x;
        cur_y = cur_y < 0 ? 0 : cur_y;
        cur_y = cur_y > div_small.offsetHeight - div_mask.offsetHeight ? div_small.offsetHeight - div_mask.offsetHeight : cur_y;

        //3.设置遮罩的(左上角)位置
        div_mask.style["left"] = cur_x + "px";
        div_mask.style["top"] = cur_y + "px";

        //4.让大图挪动(大图移动距离等于小图距离左边的宽高乘以大小图的宽高比)
        img_big.style["margin-left"] = -cur_x * img_big.offsetWidth / img_small.offsetWidth + "px";
        img_big.style["margin-top"] = -cur_y * img_big.offsetHeight / img_small.offsetHeight + "px";


    }

    //图片会在js加载完毕后才会开始加载,所以使用window.onload.
    window.onload = function () {
        //计算小图片/遮罩层的比例=大图片/大盒子的比例===>即动态设置大图片的宽高,让大图片始终贴合边框(注意:元素设置display:none后,offsetWidth这种获取宽高将会失效)
        img_big.style.width = (img_small.offsetWidth / parseFloat((window.getComputedStyle(div_mask)["width"])) * parseFloat((window.getComputedStyle(div_big)["width"]))) + "px";
        img_big.style.height = (img_small.offsetHeight / parseFloat((window.getComputedStyle(div_mask)["height"])) * parseFloat((window.getComputedStyle(div_big)["height"]))) + "px";
    }

</script>

</html>
